//////////////////////////////////////////////
// System.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkWinUi
{
	class Clipboard ;
	class ComponentManager ;
	class CursorManager ;
	class FontManager ;
	class ImageManager ;
	class InputSystem ;
	class LogManager ;
	class Notificator ;
	class ThemeManager ;
	class WindowingSystem ;
}

/// Includes ---------------------------------

// nkWinUi
#include "Dll/DllDefines.h"

// Common
#include <nilkinsCommon/Patterns/MaybeSingletonClass.h>

// nkMemory
#include <NilkinsMemory/Pointers/UniquePtr.h>

// Standards
#include <functional>

/// Class ------------------------------------

namespace nkWinUi
{
	class DLL_WINUI_EXPORT System final : public nkCommon::MaybeSingletonClass<System>
	{		
		public :

			// Constructor, destructor
			System () noexcept ;
			virtual ~System () ;

			// Getters
			WindowingSystem* getWindowingSystem () const ;
			Clipboard* getClipboard () const ;
			Notificator* getNotificator () const ;
			ComponentManager* getComponentManager () const ;
			CursorManager* getCursorManager () const ;
			FontManager* getFontManager () const ;
			ImageManager* getImageManager () const ;
			InputSystem* getInputSystem () const ;
			LogManager* getLogManager () const ;
			ThemeManager* getThemeManager () const ;
			std::function<bool ()> getRunCallback () const ;
			bool isInitialized () const ;

			// Setters
			void setRunCallback (std::function<bool ()> callback) ;

			// Start
			bool initialize () ;

			// Running
			void run () ;
			void tick () ;

			// End
			void prepareForShutdown () ;
			void shutdown () ;

			// Dummy event to trigger behaviour
			void notifyEvent () ;

		private :

			// Functions
			// Constructors
			System (bool isSingleton) noexcept ;
			System (const System&) = delete ;
			System (System&&) = delete ;

			// Start
			bool _createDefaultTheme () const ;

			// Operators
			System& operator= (const System&) = delete ;
			System& operator= (System&&) = delete ;

		private :
		
			// Attributes
			// Windowing system
			nkMemory::UniquePtr<WindowingSystem> _windowingSystem ;

			// Components
			nkMemory::UniquePtr<Clipboard> _clipboard ;
			nkMemory::UniquePtr<Notificator> _notificator ;

			ComponentManager* _componentManager ;
			CursorManager* _cursorManager ;
			FontManager* _fontManager ;
			ImageManager* _imageManager ;
			InputSystem* _inputSystem ;
			LogManager* _logManager ;
			ThemeManager* _themeManager ;

			// Callbacks
			std::function<bool ()> _runCallback ;

			// Flags
			bool _initialized ;

		private :

			friend class nkCommon::MaybeSingletonClass<System> ;
	} ;
}